export interface TreeNode {
    id: number;
    parentId: number | null;
    children?: TreeNode[];
    data: any;
}

export function findNodeById(tree: TreeNode[] = [], id: number): TreeNode | null {
    for (const node of tree) {
        if (node.id === id) {
            return node;
        }
        const found = findNodeById(node.children, id);
        if (found) {
            return found;
        }
    }
    return null;
}

export function deleteNode(tree: TreeNode[] = [], id: number): boolean {
    for (let i = 0; i < tree.length; i++) {
        if (tree[i].id === id) {
            tree.splice(i, 1);
            return true;
        }
        if (deleteNode(tree[i].children, id)) {
            return true;
        }
    }
    return false;
}

export function insertParentNode(tree: TreeNode[], id: number, newNode: TreeNode): boolean {
    const node = findNodeById(tree, id);
    if (node) {
        newNode.children?.push(...(node.children || []));
        node.children = [newNode];
        return true;
    }
    return false;
}

export function findLeafNodes(tree: TreeNode[]): TreeNode[] {
    let leaves: TreeNode[] = [];
    for (const node of tree) {
        if (node.children === undefined) {
            leaves.push(node);
        } else {
            leaves = leaves.concat(findLeafNodes(node.children));
        }
    }
    return leaves;
}

export function editLeafNode(tree: TreeNode[], id: number, newData: any): boolean {
    const node = findNodeById(tree, id);
    if (node && node.children == undefined) {
        node.data = newData;
        return true;
    }
    return false;
}

export function addNode(tree: TreeNode[],parentId?:number,data:any = {}) {
    const node:TreeNode = {id: Math.random(), parentId: parentId || null, data: data || {}};   
    if(parentId){
        const parentNode = findNodeById(tree,parentId)
        parentNode?.children?.push(node)
    }
    else{
        tree.push(node)
    }
}
